/*************************************************************************
 * Copyright 2008 David Almilli
 *  
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 *  
 *     http://www.apache.org/licenses/LICENSE-2.0 
 *      
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 **************************************************************************/
package com.tivo.hme.bananas;

import com.tivo.hme.bananas.BSkinPlus.Element;
import com.tivo.hme.interfaces.ILogger;
import com.tivo.hme.sdk.Resource;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;

public class ScaledImageElement extends Element {
    private File scaledFile;
    private String extension;

    public ScaledImageElement(BSkinPlus skin, String name, int width, int height, String resourceName) {
        this(skin, name, width, height, null, resourceName);
    }

    public ScaledImageElement(BSkinPlus skin, String name, int width, int height, String namespace, String resourceName) {
        super(skin, name, width, height, resourceName);
        
        StringBuilder sb = new StringBuilder();
        sb.append(System.getProperty("user.home")).append("/.bananas-plus/cache/");
        if (namespace != null) {
            sb.append(namespace).append('/');
        }
        int index = resourceName.lastIndexOf('.');
        if (index != -1) {
            sb.append(resourceName.substring(0, index));
            extension = resourceName.substring(index+1);
        } else {
            sb.append(resourceName);
            extension = "png";
        }
        sb.append('-').append(width).append('x').append(height);
        if (extension != null) {
            sb.append('.').append(extension);
        }
        scaledFile = new File(sb.toString());
    }
    
    public Resource createResource() {

        synchronized (skin.app) {

            Resource resource = getCachedResource(scaledFile);
            if (resource != null) {
                //the resource was already loaded by another element
                return resource;
            }
            if (!scaledFile.isFile()) {
                //scale the image
                ClassLoader loader = Thread.currentThread().getContextClassLoader();
                URL url = loader.getResource((String)resourceKey);
                if (url != null) {
                    skin.app.log(ILogger.LOG_INFO, "Scaling image " + resourceKey + 
                            " to " + scaledFile);
                    Image image = getScaledImage(url);
                    resource = skin.app.getResource(image);
                    setCachedResource(scaledFile, resource);
                    return resource;
                }
            } else {
                try {
                    BufferedImage source = ImageIO.read(scaledFile);
                    resource = skin.app.getResource(source);
                    setCachedResource(scaledFile, resource);
                    return resource;
                } catch (IOException e) {
                    skin.app.log(ILogger.LOG_NOTICE, "Cannot load scale image resource: " + 
                            scaledFile + " message=" + e.getMessage());
                }
            }
            skin.app.log(ILogger.LOG_NOTICE, "Failed to load resource: " + resourceKey);
            return null;
        }
    }
    
    private Image getScaledImage(URL url) {
        try {
            scaledFile.getParentFile().mkdirs();
            BufferedImage source = ImageIO.read(url);
            
            //scale the image
            BufferedImage resizedImage = new BufferedImage(getWidth(), getHeight(),
                    BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = resizedImage.createGraphics();
            AffineTransform at = AffineTransform.getScaleInstance((double) getWidth()
                    / source.getWidth(), (double) getHeight() / source.getHeight());
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.setRenderingHint(RenderingHints.KEY_RENDERING, 
                    RenderingHints.VALUE_RENDER_QUALITY);
            g.drawRenderedImage(source, at);
            ImageIO.write(resizedImage, extension, scaledFile);
            return resizedImage;
        } catch (IOException e) {
            skin.app.log(ILogger.LOG_NOTICE, "Cannot scale image resource: " + 
                    scaledFile + " message=" + e.getMessage());
        }
        return null;
    }
    
}
